from sc_engine.repositories import Repository

class ParticipantRepository(object):
    def __init__(self, store):
        self.store = store

    def update(self, id, name, aliases=None):
        aliases = aliases or []

        keys_to_remove = [k for k,v in self.store.items() if id in v]

        # Remove all known instances of this participant.
        for key in keys_to_remove:
            self.store[key].remove(id)

        # Add the new stuff
        for alias in aliases:
            self.store.setdefault(alias.lower(), set()).add(id)
        self.store.setdefault(name.lower(), set()).add(id)

    def find_participant(self, participant):
        """
        If one participant can be found using the name 'participant', will
        return that participant. If none or more than one are found,
        will return None.
        """
        if participant.lower() not in self.store:
            return None

        results = self.store[participant.lower()]

        if len(results) == 1:
            return list(results)[0]
        else:
            return None

    def find_participants(self, participants):
        results = set()
        for participant in participants:
            lowered = participant.lower()
            if lowered in self.store:
                results.update(self.store[lowered])
        
        return list(results)

class PlayerTeamRepository(object):
    """
    Used when trying to find participants that we are unsure if they are players
    or teams. For each participant, if it happens that it could be either a
    player or a team, it does not return the id for either. This is to prevent
    false matches for things such as if it is a game between hero and boxer, and
    "hero" could be seen as the name of MBCGame Hero. Rather than try to guess
    what it is, we'll ignore it.
    """
    def __init__(self, store):
        player_store = store.setdefault('players', {})
        team_store = store.setdefault('teams', {})

        self.player_repo = ParticipantRepository(player_store)
        self.team_repo = ParticipantRepository(team_store)

    def update_player(self, id, name, aliases=None):
        self.player_repo.update(id, name, aliases)

    def update_team(self, id, name, aliases=None):
        self.team_repo.update(id, name, aliases)

    def find_participants(self, participants):
        non_duplicates = []

        for participant in participants:
            is_player = self.player_repo.find_participants([participant])
            is_team = self.team_repo.find_participants([participant])
            if is_player and is_team:
                continue
            non_duplicates.append(participant)

                
        players = self.player_repo.find_participants(non_duplicates)
        teams = self.team_repo.find_participants(non_duplicates)

        return players, teams
